<template>
	<el-scrollbar class="plugins__wrapper" @dragover="onDragover" @drop="onDrop">
		<div class="plugins">
			<el-tabs v-model="tab.active" type="card" @tab-change="tab.onChange">
				<el-tab-pane label="已安装插件" name="installed"> </el-tab-pane>
				<el-tab-pane label="插件市场" name="shop"> </el-tab-pane>
			</el-tabs>

			<el-row :gutter="10">
				<el-col
					v-for="(item, index) in list"
					:key="index"
					:xs="24"
					:sm="12"
					:md="8"
					:lg="6"
				>
					<div class="scope">
						<div class="c">
							<el-icon class="set" @click="toSet(item)">
								<setting />
							</el-icon>

							<img class="logo" :src="'data:image/jpg;base64,' + item.logo" />

							<div class="det">
								<div class="tag">
									<el-tag size="small" effect="dark">{{ item.keyName }}</el-tag>
									<el-tag size="small" effect="dark" type="success"
										>v{{ item.version }}</el-tag
									>
								</div>

								<p class="title">
									{{ item.name || '未知' }}
								</p>

								<p class="desc">
									{{ item.description || '暂无描述' }}
								</p>

								<div class="author">
									<span>{{ item.author }}：</span>
									<span>{{ item.updateTime }}</span>
								</div>
							</div>
						</div>

						<div class="f">
							<el-button round @click="toDetail(item)">详情</el-button>
							<el-button type="danger" round @click="toDel(item, index)"
								>卸载</el-button
							>

							<cl-flex1 />

							<cl-switch
								v-model="item.status"
								@change="onStatusChange(item)"
							></cl-switch>
						</div>
					</div>
				</el-col>

				<el-col :xs="24" :sm="12" :md="8" :lg="6">
					<cl-upload :before-upload="onBeforeUpload" accept=".cool">
						<div class="scope is-add">
							<el-icon>
								<plus />
							</el-icon>
						</div>
					</cl-upload>
				</el-col>
			</el-row>

			<!-- 详情预览 -->
			<cl-editor-preview
				:ref="setRefs('editorPreview')"
				name="wang"
				:show-btn="false"
				:title="`${info?.name} v${info?.version} 说明文档`"
			>
				<template #prepend>
					<div class="info-header">
						<span>作者：{{ info?.author }}</span>
						<span>更新时间：{{ info?.updateTime }}</span>
					</div>
				</template>
			</cl-editor-preview>

			<!-- 设置 -->
			<cl-form ref="Form">
				<template #slot-upload>
					<cl-row>
						<cl-upload-space
							:show-list="false"
							:multiple="false"
							text="选择文件"
							@confirm="onFileConfirm"
						/>

						<el-text type="warning" :style="{ marginLeft: '10px' }"
							>选择后会在光标后插入文件链接</el-text
						>
					</cl-row>
				</template>
			</cl-form>
		</div>
	</el-scrollbar>
</template>

<script lang="ts" setup name="helper-plugins-serve">
import { onActivated, reactive, ref, nextTick } from 'vue';
import { useCool } from '/@/cool';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Plus, Setting } from '@element-plus/icons-vue';
import { marked } from 'marked';
import { useForm } from '@cool-vue/crud';
import { merge } from 'lodash-es';

const { service, refs, setRefs } = useCool();
const Form = useForm();

// 选项卡
const tab = reactive({
	active: 'installed',

	onChange(val: any) {
		if (val == 'shop') {
			nextTick(() => {
				tab.active = 'installed';
				window.open('https://cool-js.com/plugin');
			});
		}
	}
});

// 插件列表
const list = ref<Eps.PluginInfoEntity[]>([]);

// 插槽详情
const info = ref<Eps.PluginInfoEntity>();

// 刷新
function refresh() {
	service.plugin.info.page({ page: 1, size: 100 }).then(res => {
		list.value = res.list;
	});
}

// 参数设置
function toSet(item: Eps.PluginInfoEntity) {
	Form.value?.open({
		title: '设置',

		props: {
			labelWidth: '60px'
		},

		form: {
			...item
		},

		items: [
			{
				label: '参数',
				prop: 'config',
				value: '{}',
				component: {
					name: 'cl-editor',
					props: {
						name: 'cl-editor-monaco',
						ref: setRefs('editor')
					}
				}
			},
			{
				label: ' ',
				flex: false,
				component: {
					name: 'slot-upload'
				}
			},
			{
				label: '状态',
				prop: 'status',
				component: {
					name: 'cl-switch'
				}
			}
		],

		on: {
			submit(data, { done, close }) {
				try {
					const config = JSON.parse(data.config);

					service.plugin.info
						.update({
							config,
							id: data.id,
							status: data.status
						})
						.then(() => {
							ElMessage.success('修改成功');
							merge(item, data);
							close();
						})
						.catch(err => {
							ElMessage.error(err.message);
							done();
						});
				} catch (e) {
					ElMessage.error('参数格式错误，请检查');
					done();
				}
			}
		}
	});
}

// 详情
async function toDetail(item: Eps.PluginInfoEntity) {
	info.value = item;
	refs.editorPreview.open(await marked.parse(item.readme!));
}

// 卸载
function toDel(item: Eps.PluginInfoEntity, index: number) {
	ElMessageBox.confirm(`确定要卸载插件【${item.name}】吗？`, '提示', {
		type: 'warning'
	})
		.then(() => {
			service.plugin.info
				.delete({
					ids: [item.id]
				})
				.then(() => {
					list.value.splice(index, 1);
					ElMessage.success('卸载成功');
				})
				.catch(err => {
					ElMessage.error(err.message);
				});
		})
		.catch(() => null);
}

// 文件选择
function onFileConfirm(arr: any[]) {
	refs.editor.appendContent(arr[0]?.url);
}

// 状态修改
function onStatusChange(item: Eps.PluginInfoEntity) {
	service.plugin.info
		.update({
			id: item.id,
			status: item.status
		})
		.then(() => {
			ElMessage.success(item.status ? '开启成功' : '关闭成功');
		})
		.catch(err => {
			ElMessage.error(err.message);
		});
}

// 上传
function onBeforeUpload(file: File) {
	function next(force: string) {
		const formData = new FormData();

		formData.append('files', file);
		formData.append('force', force);

		service.plugin.info
			.request({
				url: '/install',
				method: 'POST',
				data: formData,
				headers: {
					'Content-Type': 'multipart/form-data'
				}
			})
			.then(res => {
				if (res) {
					ElMessageBox.confirm(res.message, '提示', {
						type: 'warning',
						confirmButtonText: '继续'
					})
						.then(() => {
							next('true');
						})
						.catch(() => null);
				} else {
					ElMessage.success('插件安装成功');
					refresh();
				}
			})
			.catch(err => {
				ElMessage.error(err.message);
			});
	}

	next('false');

	return false;
}

// 拖拽
function onDragover(e: DragEvent) {
	e.preventDefault();
}

// 放下
function onDrop(e: DragEvent) {
	e.preventDefault();

	if (e.dataTransfer) {
		const file = e.dataTransfer.files[0];

		ElMessageBox.confirm('检测到插件，是否安装', '提示', {
			type: 'warning',
			confirmButtonText: '安装'
		})
			.then(() => {
				onBeforeUpload(file);
			})
			.catch(() => null);
	}
}

onActivated(() => {
	refresh();
});
</script>

<style lang="scss" scoped>
@forward '../../static/index.scss';

.info-header {
	display: flex;
	align-items: center;
	font-size: 13px;
	margin-bottom: 15px;

	span {
		margin-right: 20px;
		line-height: 1;
	}
}
</style>
